package hr.ctg.domain.action;

import hr.ctg.domain.model.Dogadjaj;
import hr.ctg.domain.model.Jezik;
import hr.ctg.domain.model.Korisnik;
import hr.ctg.domain.model.Mjesto;
import hr.ctg.domain.model.Opis;
import hr.ctg.domain.model.Slika;
import hr.ctg.service.dao.DogadjajDAO;
import hr.ctg.service.dao.JezikDAO;
import hr.ctg.service.dao.MjestoDAO;
import hr.ctg.service.dao.SlikaDAO;
import hr.ctg.util.CacheUtil;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.log.Log;
import org.joda.time.DateTime;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

@Name("dogadjajAction")
@Scope(ScopeType.CONVERSATION)
public class DogadjajAction {
	private static final SimpleDateFormat sdf = new SimpleDateFormat(
			"MMM dd yyyy hh:mm:ss", Locale.US);

	@In
	DogadjajDAO dogadjajDAO;
	@In
	MjestoDAO mjestoDAO;
	@In
	SlikaDAO slikaDAO;
	@In
	JezikDAO jezikDAO;
	@In
	FacesMessages facesMessages;
	@In(required = false)
	String currentLang;
	@In(required = false)
	Korisnik korisnik;
	@In(create = true)
	SlikaAction slikaAction;

	@Logger
	Log log;

	@RequestParameter
	Integer idMjesta;
	@RequestParameter
	Integer idOtoka;
	@RequestParameter
	Integer idZupanije;

	private String back;
	private Opis opis;
	private Mjesto mjesto;
	private List<Jezik> dostupniJezici = new ArrayList<Jezik>();

	@DataModel
	private final Set<Opis> opisi = new HashSet<Opis>();

	@SuppressWarnings("unused")
	@DataModel
	private List<Dogadjaj> dogadjaji;
	@DataModelSelection("dogadjaji")
	@In(required = false)
	@Out(required = false)
	private Dogadjaj dogadjaj;
	@In(required = false)
	@Out(required = false)
	private Slika slika;
	private List<Slika> uneseneSlike;

	// private boolean otherUserImagesPresent;

	@Begin
	public String addSetup(final String back) {
		this.back = back;
		mjesto = mjestoDAO.find(idMjesta);
		dogadjaj = new Dogadjaj();
		opis = new Opis();
		dostupniJezici.addAll(jezikDAO.findAll());

		uneseneSlike = new ArrayList<Slika>();

		return "addDogadjaj";
	}

	public void addOpis() {
		if (opis.getNaziv() != null && opis.getOpis() != null) {
			dostupniJezici.remove(opis.getJezik());
			opis.setDogadjaj(dogadjaj);
			opisi.add(opis);
			opis = new Opis();
		}
	}

	@End(beforeRedirect = true)
	@Transactional
	public String add() {
		if (opisi.isEmpty()) {
			facesMessages.addToControlFromResourceBundle("",
					FacesMessage.SEVERITY_ERROR, "message.name_not_defined");
			return null;
		}
		if (dogadjaj.isTrajanje()) {
			if (dogadjaj.getDatumDo() == null) {
				facesMessages.addToControlFromResourceBundle("",
						FacesMessage.SEVERITY_ERROR,
						"message.date_to_not_defined");
				return null;
			}
		}
		dogadjaj.setKorisnik(korisnik);
		dogadjaj.setMjesto(mjesto);
		dogadjaj.getOpisDogadjajas().addAll(opisi);
		// addSlika();
		// dogadjaj.getSlikas().addAll(uneseneSlike);
		dogadjajDAO.persist(dogadjaj);

		for (Slika slika : uneseneSlike) {
			slikaDAO.persist(slika);
			slikaDAO.flush();
			slikaAction.saveImageToFileSystem(slika);
		}

		CacheUtil.clearCache(mjesto, currentLang);

		return back;
	}

	@End
	public String cancel() {
		return back;
	}

	public Dogadjaj getDogadjaj() {
		return dogadjaj;
	}

	public void setDogadjaj(final Dogadjaj dogadjaj) {
		this.dogadjaj = dogadjaj;
	}

	public Opis getOpis() {
		return opis;
	}

	public void setOpis(final Opis opis) {
		this.opis = opis;
	}

	public String getToday() {
		return sdf.format(new DateTime().toDateMidnight().toDate());
	}

	public String getWeekStartDate() {
		return sdf.format(new DateTime().withDayOfMonth(1).toDateMidnight()
				.toDate());
	}

	public String getWeekEndDate() {
		return sdf.format(new DateTime().withDayOfMonth(1).plusMonths(1)
				.toDateMidnight().toDate());
	}

	public String getDayStartDate() {
		return sdf
				.format(new DateTime().minusDays(1).toDateMidnight().toDate());
	}

	public String getDayEndDate() {
		return sdf.format(new DateTime().plusDays(1).toDateMidnight().toDate());
	}

	public boolean hasDogadjaj() {
		if (idOtoka != null) {
			return dogadjajDAO.findCountByIdOtoka(idOtoka) > 0 ? true : false;
		} else if (idZupanije != null) {
			return dogadjajDAO.findCountByIdZupanije(idZupanije) > 0 ? true
					: false;
		} else if (idMjesta != null) {
			return dogadjajDAO.findCountByIdMjesta(idMjesta) > 0 ? true : false;
		} else {
			return true;
		}
	}

	@Factory("dogadjaji")
	public void getDogadjaji() {
		if (idMjesta != null) {
			dogadjaji = dogadjajDAO.findByIdMjesta(idMjesta);
		} else if (idOtoka != null) {
			dogadjaji = dogadjajDAO.findByIdOtoka(idOtoka);
		} else if (idZupanije != null) {
			dogadjaji = dogadjajDAO.findByIdZupanije(idZupanije);
		} else {
			dogadjaji = dogadjajDAO.findByCurrentDate();
		}
	}

	@Begin(join = true)
	public String editSetup(final String back) {
		this.back = back;
		mjesto = mjestoDAO.find(dogadjaj.getMjesto().getIdMjesta());
		this.opis = new Opis();
		this.opisi.addAll(dogadjaj.getOpisDogadjajas());
		dostupniJezici.addAll(jezikDAO.findAll());
		for (final Opis o : this.opisi)
			dostupniJezici.remove(o.getJezik());

		uneseneSlike = slikaDAO.findByIdDogadjaja(dogadjaj.getIdDogadjaja());
		for (Slika s : uneseneSlike) {
			slikaAction.readImageFromFileSystem(s);
		}

		return "editDogadjaj";
	}

	@End(beforeRedirect = true)
	public String edit() {
		dogadjaj.getOpisDogadjajas().clear();
		if (opisi.isEmpty()) {
			facesMessages.addToControlFromResourceBundle("retrieveMessage",
					FacesMessage.SEVERITY_ERROR,
					"message.user.email.dont.exists");
			return null;
		}
		dogadjaj.getOpisDogadjajas().addAll(opisi);
		// dogadjaj.getSlikas().addAll(uneseneSlike);
		dogadjajDAO.merge(dogadjaj);

		for (Slika slika : uneseneSlike) {
			slikaDAO.persist(slika);
			slikaDAO.flush();
			slikaAction.saveImageToFileSystem(slika);
		}

		CacheUtil.clearCache(mjesto, currentLang);
		CacheUtil.clearCache(dogadjaj);

		return back;
	}

	@End(beforeRedirect = true)
	public String delete() {
		dogadjaj = dogadjajDAO.merge(dogadjaj);
		dogadjajDAO.remove(dogadjaj);

		return back;
	}

	public List<Jezik> getDostupniJezici() {
		return dostupniJezici;
	}

	public void setDostupniJezici(final List<Jezik> dostupniJezici) {
		this.dostupniJezici = dostupniJezici;
	}

	public void processSlika(final UploadEvent ue) {
		log.debug("Unosim slike...");
		log.debug("Dogadjaj -> " + dogadjaj);
		for (final UploadItem ui : ue.getUploadItems()) {
			slika = new Slika();
			slika.setKorisnik(korisnik);
			slika.setDogadjaj(dogadjaj);
			if (uneseneSlike.size() == 0) {
				slika.setPocetna(true);
			}
			// FileInputStream is = null;
			// try {
			// is = new FileInputStream(ui.getFile());
			// } catch (FileNotFoundException e) {
			// e.printStackTrace();
			// }
			// byte[] data = new byte[ui.getFileSize()];
			// try {
			// is.read(data);
			// } catch (IOException e) {
			// e.printStackTrace();
			// }
			// try {
			// is.close();
			// } catch (IOException e) {
			// e.printStackTrace();
			// }
			slika.setSadrzaj(ui.getData());
			log.debug("Datoteka: " + ui.getFileName());
			slika.setOpis(ui.getFileName());
			slika.setTipSadrzaja(ui.getContentType());
			uneseneSlike.add(slika);
		}
		log.debug("Prisutno slika: " + uneseneSlike.size());
		FacesContext.getCurrentInstance().renderResponse();
	}

	public List<Slika> getUneseneSlike() {
		return uneseneSlike;
	}

	public void setUneseneSlike(final List<Slika> uneseneSlike) {
		this.uneseneSlike = uneseneSlike;
	}

	public void ukloniSliku(final Slika zaUkloniti) {
		log.debug("Uklanjam: " + zaUkloniti.getOpis(), new Object[0]);
		uneseneSlike.remove(zaUkloniti);
		if (dogadjaj.getSlikas().contains(zaUkloniti)) {
			dogadjaj.getSlikas().remove(zaUkloniti);
			slikaDAO.remove(zaUkloniti);
		}
		if (zaUkloniti.isPocetna() && uneseneSlike.size() > 0) {
			uneseneSlike.get(0).setPocetna(true);
		}
	}

}
